﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using MainScene;

namespace SSShell
{
    class Analisator
    {
        private List<string> lstScenes = new List<string>();
        private string fileName = "";//путь к файлу
        private bool isRec = false;

        public Analisator(string txtFileName)
        {
            fileName = txtFileName;
        }

        private void DelEmpty(List<string> lstSTR)
        {
            for (int count=0; count < lstSTR.Count;count++)
                lstSTR[count] = lstSTR[count].Trim();
            int i=0;
            while (i < lstSTR.Count)
            {
                if (lstSTR[i] == "" || lstSTR[i] == "\r")
                    lstSTR.RemoveAt(i);
                else i++;
            }
        }

        private string GetRoleOfAgent(Taxonomia tax,string hero)
        {
            string str = hero;
            if (str.Contains(' '))
                str=str.Substring(str.IndexOf(' ')+1);
            foreach (Role role in tax.Roles)
            {
                foreach (string h in role.Heroes)
                {
                    if (h.Length < str.Length)
                    {
                        if (h.Trim().ToUpper().Substring(0, h.Length - 1) == str.Trim().ToUpper().Substring(0, h.Length - 1))
                            return role.Name;
                    }
                    else
                    {
                        if (h.Trim().ToUpper().Substring(0, str.Length - 1) == str.Trim().ToUpper().Substring(0, str.Length - 1))
                            return role.Name;
                    }
                }
            }
            int i=0;
            while (!tax.AddRole("Персонаж" + i.ToString()))
                i++;
            tax.GetRole("Персонаж" + i.ToString()).AddHero(str);
            return tax.GetRole("Персонаж" + i.ToString()).Name;
        }

        private void DelPred(List<string> lstSTR)
        {
            int i = 0;
            while (i < lstSTR.Count)
            {
                if (lstSTR[i] == "на" || lstSTR[i] == "в" || lstSTR[i] == "из")
                {
                    if (lstSTR.Count > i + 1)
                    {
                        if (Char.IsUpper(lstSTR[i + 1][0]))
                            isRec = true;
                        lstSTR[i + 1] = lstSTR[i] + ' ' + lstSTR[i + 1];
                        lstSTR.RemoveAt(i);
                    }
                }
                else
                {
                    if (Char.IsUpper(lstSTR[i][0]) && i>1)
                        isRec = true;
                    i++;
                }
            }
        }

        private void MakeListScene()
        {
            Encoding enc = Encoding.GetEncoding(1251);
            StreamReader sr = new StreamReader(fileName,enc);
            string allFile=sr.ReadToEnd();
            lstScenes = allFile.Split('\n').ToList();
            DelEmpty(lstScenes);
        }

        private ClassSemanticNet GetListNodes(ClassNode main)
        {
            ClassNode currNode = main;
            ClassSemanticNet SS = new ClassSemanticNet();
            currNode.ArriveFrom = null;
            currNode.LastParent = null;
            while (currNode.LastParent != null || currNode.ArriveFrom != currNode.LstNodes[currNode.LstNodes.Count - 1])//пока не обошли все ветви
            {
                if (currNode.TypeN == TypeNode.Action)//если действие
                {
                    if (!SS.LstNodes.Contains(currNode))
                        SS.LstNodes.Add(currNode);
                    currNode.ArriveFrom.ArriveFrom = currNode;
                    currNode = currNode.ArriveFrom;//переход на сцену, откуда пришли
                }
                else //если сцена
                {
                    if (currNode.ArriveFrom == currNode.LastParent)//если только спустились
                    {
                        if (currNode.LstNodes.Count == 0)
                            return null;//ошибка: сцена не ссылается на действия
                        if (!SS.LstNodes.Contains(currNode))
                            SS.LstNodes.Add(currNode);
                        currNode.LstNodes[0].ArriveFrom = currNode;
                        currNode.LstNodes[0].LastParent = currNode;
                        currNode = currNode.LstNodes[0];
                    }
                    else if (currNode.LstNodes.IndexOf(currNode.ArriveFrom) < currNode.LstNodes.Count - 1)//уже обошли часть потомков
                    {
                        currNode.LstNodes[currNode.LstNodes.IndexOf(currNode.ArriveFrom) + 1].ArriveFrom = currNode;
                        currNode.LstNodes[currNode.LstNodes.IndexOf(currNode.ArriveFrom) + 1].LastParent = currNode;
                        currNode = currNode.LstNodes[currNode.LstNodes.IndexOf(currNode.ArriveFrom) + 1];//выбираем следующего потомка
                    }
                    else if (currNode.LstNodes.IndexOf(currNode.ArriveFrom) == currNode.LstNodes.Count - 1)//обошли всех потомков
                    {//значит совершен обход сцены
                        if (currNode.LastParent != null)//не корневая вершина
                        {
                            currNode.LastParent.ArriveFrom = currNode;
                            currNode = currNode.LastParent;
                        }
                    }
                }
            }
            return SS;
        }

        private Taxonomia CreateTaxonomy()
        {
            Taxonomia tax = new Taxonomia();
            Role currRole=null;
            bool IsEnd = false;
            while (!IsEnd)
            {
                if (lstScenes.Count == 0)
                    IsEnd = true;
                else if (lstScenes[0][0] == '>')
                {
                    if (lstScenes[0][1] == '>')
                    {
                        if (currRole==null)
                            tax.AddRole(lstScenes[0].Substring(1));
                        else currRole.AddHero(lstScenes[0].Substring(2));
                    }
                    else { 
                        tax.AddRole(lstScenes[0].Substring(1));
                        currRole = tax.GetRole(lstScenes[0].Substring(1));
                    }
                    lstScenes.RemoveAt(0);
                }
                else IsEnd = true;
            }
            return tax;
        }

        public ClassSemanticNet GetSN()
        {
            Taxonomia myTax;
            List<string> lstActions=new List<string>();
            List<string> lstCase=new List<string>();
            int id = 0;
            ClassSemanticNet newSS = new ClassSemanticNet();
            ClassNode parent;
            //////////////////////////////////////////////////
            newSS.AddScene("id" + id.ToString());
            //ClassNode Net = new ClassNode(TypeNode.Scene);
            //Net.Name ="id"+id.ToString();
            id++;
            newSS.LstNodes[0].MaxBrowse = 0;
            newSS.LstNodes[0].ArriveFrom = null;
            newSS.LstNodes[0].LastParent = null;
            //ClassNode Node = Net;
            //ClassNode newNode;
            MakeListScene();
            myTax=CreateTaxonomy();
            newSS.Taxon = myTax;
            foreach (string str in lstScenes)
            {
                newSS.AddScene("id" + id.ToString());
                //newNode=new ClassNode(TypeNode.Scene);
                //newNode.Name = "id" + id.ToString();
                id++;
                newSS.LstNodes[newSS.LstNodes.Count-1].MaxBrowse = 0;
                newSS.LstNodes[0].LstNodes.Add(newSS.LstNodes[newSS.LstNodes.Count - 1]);
                newSS.LstNodes[newSS.LstNodes.Count - 1].LstParent.Add(newSS.LstNodes[0]);
                newSS.LstNodes[newSS.LstNodes.Count - 1].LastParent = newSS.LstNodes[0];
                newSS.LstNodes[newSS.LstNodes.Count - 1].ArriveFrom = newSS.LstNodes[0];
                parent = newSS.LstNodes[newSS.LstNodes.Count - 1];
                //newSS.LstNodes[0] = newNode;
                lstActions = str.Split('.','?','!').ToList();
                DelEmpty(lstActions);
                for (int i=0; i < lstActions.Count;i++)
                {
                    lstCase=lstActions[i].Split(' ').ToList();
                    DelEmpty(lstCase);
                    isRec = false;
                    DelPred(lstCase);
                    //newSS.AddAction()
                    //newNode=new ClassNode(TypeNode.Action);
                    //newNode.LstParent.Add(Node);
                    //Node.LstNodes.Add(newNode);
                    //newNode.CaseFrame = new ClassCaseFrame();
                    //newNode.CaseFrame.Agent = new ClassCase();
                    //newNode.CaseFrame.Recipient = new ClassCase();
                    //newNode.CaseFrame.Lokotiv = new ClassCase();
                    //newNode.CaseFrame.Obj = new ClassCase();
                    //newNode.CaseFrame.Time = new ClassCase();
                    //newNode.CaseFrame.ToDo = new ClassCase();


                    if (lstCase.Count==3)
                    {
                        if (isRec)
                        {
                            newSS.AddAction(GetRoleOfAgent(myTax, lstCase[0]),GetRoleOfAgent(myTax, lstCase[2]),lstCase[1],"","","",0,0);
                            //newNode.CaseFrame.Lokotiv.Name = "";
                            //newNode.CaseFrame.Recipient.Name = GetRoleOfAgent(myTax, lstCase[2]);
                        }
                        else
                        {
                            newSS.AddAction(GetRoleOfAgent(myTax, lstCase[0]), "", lstCase[1], lstCase[2], "", "", 0, 0);
                            //newNode.CaseFrame.Lokotiv.Name = lstCase[2];
                            //newNode.CaseFrame.Recipient.Name = "";
                        }
                        //newNode.CaseFrame.Obj.Name = "";
                        //newNode.CaseFrame.Agent.Name = GetRoleOfAgent(myTax,lstCase[0]);
                        //newNode.CaseFrame.Time.Name = "";
                        //newNode.CaseFrame.ToDo.Name = lstCase[1];
                    }
                    else if (lstCase.Count==4)
                    {
                        if (isRec)
                        {
                            newSS.AddAction(GetRoleOfAgent(myTax, lstCase[0]), GetRoleOfAgent(myTax, lstCase[2]), lstCase[1], "", "",lstCase[3], 0, 0);
                            //newNode.CaseFrame.Lokotiv.Name = "";
                            //newNode.CaseFrame.Recipient.Name = GetRoleOfAgent(myTax, lstCase[2]);
                            //newNode.CaseFrame.Obj.Name = lstCase[3];
                        }
                        else
                        {
                            newSS.AddAction(GetRoleOfAgent(myTax, lstCase[0]), "", lstCase[1], lstCase[3], "", lstCase[2], 0, 0);
                            //newNode.CaseFrame.Lokotiv.Name = lstCase[3];
                            //newNode.CaseFrame.Recipient.Name = "";
                            //newNode.CaseFrame.Obj.Name =  lstCase[2];
                        }
                        //newNode.CaseFrame.Agent.Name = GetRoleOfAgent(myTax, lstCase[0]);
                        //newNode.CaseFrame.Time.Name = "";
                        //newNode.CaseFrame.ToDo.Name = lstCase[1];
                    }
                    else 
                    {
                        newSS.AddAction("", "", "", "", "", lstActions[i], 0, 0);
                        //newNode.CaseFrame.Agent.Name="";
                        //newNode.CaseFrame.Recipient.Name ="";
                        //newNode.CaseFrame.Lokotiv.Name ="";
                        //newNode.CaseFrame.Obj.Name =lstActions[i];
                        //newNode.CaseFrame.Time.Name ="";
                        //newNode.CaseFrame.ToDo.Name="";
                    } 
                    newSS.LstNodes[newSS.LstNodes.Count - 1].LstParent.Add(parent);
                    parent.LstNodes.Add(newSS.LstNodes[newSS.LstNodes.Count - 1]);                   
                }
            }
            //ClassSemanticNet snet=GetListNodes(Net);
            //snet.Taxon = myTax;
            Cord(newSS);
            return newSS;
        }

        void Cord(ClassSemanticNet sn)
        {
            int i=10;
            int j = 9;
            foreach (ClassNode cn in sn.LstNodes)
            {
                cn.X=i;
                cn.X_d2 = i;
                cn.Y =j;
                cn.Y_d2 = j;
                if (i > j) 
                    j += 10;
                else i += 10;
            }
        }

    }
}
